home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / gnus / gnus-undo.el.z / gnus-undo.el
Encoding:
Text File  |  1998-05-21  |  5.5 KB  |  175 lines

  1. ;;; gnus-undo.el --- minor mode for undoing in Gnus
  2. ;; Copyright (C) 1996,97 Free Software Foundation, Inc.
  3.  
  4. ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
  5. ;; Keywords: news
  6.  
  7. ;; This file is part of GNU Emacs.
  8.  
  9. ;; GNU Emacs is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; GNU Emacs is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  21. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  22. ;; Boston, MA 02111-1307, USA.
  23.  
  24. ;;; Commentary:
  25.  
  26. ;; This package allows arbitrary undoing in Gnus buffers.  As all the
  27. ;; Gnus buffers aren't very text-oriented (what is in the buffers is
  28. ;; just some random representation of the actual data), normal Emacs
  29. ;; undoing doesn't work at all for Gnus.
  30. ;;
  31. ;; This package works by letting Gnus register functions for reversing
  32. ;; actions, and then calling these functions when the user pushes the
  33. ;; `undo' key.  As with normal `undo', there it is possible to set
  34. ;; undo boundaries and so on.
  35. ;;
  36. ;; Internally, the undo sequence is represented by the
  37. ;; `gnus-undo-actions' list, where each element is a list of functions
  38. ;; to be called, in sequence, to undo some action.  (An "action" is a
  39. ;; collection of functions.)
  40. ;;
  41. ;; For instance, a function for killing a group will call
  42. ;; `gnus-undo-register' with a function that un-kills the group.  This
  43. ;; package will put that function into an action.
  44.  
  45. ;;; Code:
  46.  
  47. (eval-when-compile (require 'cl))
  48.  
  49. (require 'gnus-util)
  50. (require 'gnus)
  51.  
  52. (defvar gnus-undo-mode nil
  53.   "Minor mode for undoing in Gnus buffers.")
  54.  
  55. (defvar gnus-undo-mode-hook nil
  56.   "Hook called in all `gnus-undo-mode' buffers.")
  57.  
  58. ;;; Internal variables.
  59.  
  60. (defvar gnus-undo-actions nil)
  61. (defvar gnus-undo-boundary t)
  62. (defvar gnus-undo-last nil)
  63. (defvar gnus-undo-boundary-inhibit nil)
  64.  
  65. ;;; Minor mode definition.
  66.  
  67. (defvar gnus-undo-mode-map nil)
  68.  
  69. (unless gnus-undo-mode-map
  70.   (setq gnus-undo-mode-map (make-sparse-keymap))
  71.  
  72.   (gnus-define-keys gnus-undo-mode-map
  73.    "\M-\C-_"     gnus-undo
  74.    "\C-_"        gnus-undo
  75.    "\C-xu"       gnus-undo
  76.    ;; many people are used to type `C-/' on X terminals and get `C-_'.
  77.    [(control /)] gnus-undo))
  78.  
  79. (defun gnus-undo-make-menu-bar ()
  80.   ;; This is disabled for the time being.
  81.   (when nil
  82.     (define-key-after (current-local-map) [menu-bar file gnus-undo]
  83.       (cons "Undo" 'gnus-undo-actions)
  84.       [menu-bar file whatever])))
  85.  
  86. (defun gnus-undo-mode (&optional arg)
  87.   "Minor mode for providing `undo' in Gnus buffers.
  88.  
  89. \\{gnus-undo-mode-map}"
  90.   (interactive "P")
  91.   (set (make-local-variable 'gnus-undo-mode)
  92.        (if (null arg) (not gnus-undo-mode)
  93.      (> (prefix-numeric-value arg) 0)))
  94.   (set (make-local-variable 'gnus-undo-actions) nil)
  95.   (set (make-local-variable 'gnus-undo-boundary) t)
  96.   (when gnus-undo-mode
  97.     ;; Set up the menu.
  98.     (when (gnus-visual-p 'undo-menu 'menu)
  99.       (gnus-undo-make-menu-bar))
  100.     (gnus-add-minor-mode 'gnus-undo-mode "" gnus-undo-mode-map)
  101.     (make-local-hook 'post-command-hook)
  102.     (add-hook 'post-command-hook 'gnus-undo-boundary nil t)
  103.     (run-hooks 'gnus-undo-mode-hook)))
  104.  
  105. ;;; Interface functions.
  106.  
  107. (defun gnus-disable-undo (&optional buffer)
  108.   "Disable undoing in the current buffer."
  109.   (interactive)
  110.   (save-excursion
  111.     (when buffer
  112.       (set-buffer buffer))
  113.     (gnus-undo-mode -1)))
  114.  
  115. (defun gnus-undo-boundary ()
  116.   "Set Gnus undo boundary."
  117.   (if gnus-undo-boundary-inhibit
  118.       (setq gnus-undo-boundary-inhibit nil)
  119.     (setq gnus-undo-boundary t)))
  120.  
  121. (defun gnus-undo-force-boundary ()
  122.   "Set Gnus undo boundary."
  123.   (setq gnus-undo-boundary-inhibit nil
  124.     gnus-undo-boundary t))
  125.  
  126. (defun gnus-undo-register (form)
  127.   "Register FORMS as something to be performed to undo a change.
  128. FORMS may use backtick quote syntax."
  129.   (when gnus-undo-mode
  130.     (gnus-undo-register-1
  131.      `(lambda ()
  132.     ,form))))
  133.  
  134. (put 'gnus-undo-register 'lisp-indent-function 0)
  135. (put 'gnus-undo-register 'edebug-form-spec '(body))
  136.  
  137. (defun gnus-undo-register-1 (function)
  138.   "Register FUNCTION as something to be performed to undo a change."
  139.   (when gnus-undo-mode
  140.     (cond
  141.      ;; We are on a boundary, so we create a new action.
  142.      (gnus-undo-boundary
  143.       (push (list function) gnus-undo-actions)
  144.       (setq gnus-undo-boundary nil))
  145.      ;; Prepend the function to an old action.
  146.      (gnus-undo-actions
  147.       (setcar gnus-undo-actions (cons function (car gnus-undo-actions))))
  148.      ;; Initialize list.
  149.      (t
  150.       (setq gnus-undo-actions (list (list function)))))
  151.     (setq gnus-undo-boundary-inhibit t)))
  152.  
  153. (defun gnus-undo (n)
  154.   "Undo some previous changes in Gnus buffers.
  155. Repeat this command to undo more changes.
  156. A numeric argument serves as a repeat count."
  157.   (interactive "p")
  158.   (unless gnus-undo-mode
  159.     (error "Undoing is not enabled in this buffer"))
  160.   (message "%s" last-command)
  161.   (when (or (not (eq last-command 'gnus-undo))
  162.         (not gnus-undo-last))
  163.     (setq gnus-undo-last gnus-undo-actions))
  164.   (let ((action (pop gnus-undo-last)))
  165.     (unless action
  166.       (error "Nothing further to undo"))
  167.     (setq gnus-undo-actions (delq action gnus-undo-actions))
  168.     (setq gnus-undo-boundary t)
  169.     (while action
  170.       (funcall (pop action)))))
  171.  
  172. (provide 'gnus-undo)
  173.  
  174. ;;; gnus-undo.el ends here
  175.